import { Component, OnInit, ViewChild, Injector, ElementRef } from '@angular/core';
import { SetPathModalComponent } from './set-path-modal/set-path-modal.component';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import {
  ServiceProxy,
  WarehouseDTO,
  SiteDTO,
  PathDTO,
  DispatchDTO
} from '@shared/service-proxy/service-proxies';
import { AppComponentBase } from '@shared/common/app-component-base';
import { loadModules } from 'esri-loader';
import esri = __esri;
import * as moment from 'moment';
import { Router } from '@angular/router';
import { AppConsts } from '@shared/AppConsts';

@Component({
  selector: 'app-path-create',
  templateUrl: './path-create.component.html',
  styleUrls: ['./path-create.component.less']
})
export class PathCreateComponent extends AppComponentBase implements OnInit {
  @ViewChild('setPathModal') setPathModal: SetPathModalComponent;
  @ViewChild('mapViewNode') private mapViewEl: ElementRef;

  companyList: WarehouseDTO[] = [];
  startCompanyList: WarehouseDTO[] = [];
  endCompanyList: WarehouseDTO[] = [];
  sites: SiteDTO[] = [];
  bySites: SiteDTO[] = [];
  model: PathDTO = new PathDTO();
  validateForm: FormGroup;
  pathList: DispatchDTO[] = [];
  tempPathList: DispatchDTO[] = [];
  typeList: any[];
  selectedPath: string = '';
  disabledSelect: boolean = false;
  legendShow: boolean = false;

  constructor(injector: Injector,
    private fb: FormBuilder,
    private router: Router,
    private _service: ServiceProxy) {
    super(injector);
  }

  ngOnInit() {
    this.setMapView();
    $(window).resize(() => {
      this.setMapView();
    });
    if (!this.isGranted('A8_B23_C31_')) {
      if (this.isGranted('A8_B23_C30_')) {
        this.router.navigate(['/center/path/pathManagement']);
      }
    }

    console.log(AppConsts.serverBaseUrl);

    this.validateForm = this.fb.group({
      startSiteId: [null, [Validators.required]],
      endSiteId: [null, [Validators.required]],
      startWarehouseId: [null, [Validators.nullValidator]],
      endWarehouseId: [null, [Validators.nullValidator]],
      pathNo: [null, [Validators.required,Validators.maxLength(255)]],
      defaultFlag: [null, [Validators.required]],
      type: [null, [Validators.nullValidator]],
      parentId: [null, [Validators.nullValidator]],
    });

    this.getAllSites();
    this.getSitesBySite();
    this.getAllCompany();
    this.model = new PathDTO();
    this.model.defaultFlag = false;
    this.model.type = "1";
    this.typeList = [
      { label: this.l("freehand_sketching"), value: '1' },
      { label: this.l("select_path"), value: '2' }];
  }
  setMapView() {
    const $mapview = $('.esri-view');
    $mapview.height($(window).innerHeight() - 240);
  }
  getSitesBySite() {
    this._service.getAllSitesBySiteUsingGET().subscribe(result => {
      this.bySites = result.result.fieldList;
    });
  }

  getAllSites() {
    this._service.getAllSitesUsingGET().subscribe(result => {
      this.sites = result.result.fieldList;
    });
  }

  getAllCompany() {
    this._service.getAllWarehouseDTOsUsingGET().subscribe(result => {
      this.companyList = result.result.fieldList;
    });
  }

  getCompanyForStart() {
    this.model.startWarehouseId = "";
    this.startCompanyList = this.companyList.filter(m => m.siteId == this.model.startSiteId);
    this.getPathList();
    this.startSite = this.sites.find(m => m.id == this.model.startSiteId);

    if (this.startSite)
      this._center = [this.startSite.lng, this.startSite.lat];

    this.initializeMap();

  }

  getCompanyForEnd() {
    this.model.endWarehouseId = "";
    this.endCompanyList = this.companyList.filter(m => m.siteId == this.model.endSiteId);
    this.getPathList();
    this.endSite = this.sites.find(m => m.id == this.model.endSiteId);

  }

  ceratePath() {
    for (const i in this.validateForm.controls) {
      this.validateForm.controls[i].markAsDirty();
      this.validateForm.controls[i].updateValueAndValidity();
    }

    if (this.validateForm.valid) { // 验证通过
      this._service.createPathUsingPOST(this.model).subscribe(result => {
        if (result.success) {
          this.message.success(this.l('save_success'));
          this.model = new PathDTO();
          this.validateForm.reset();
        }
        else {
          this.message.info(this.l(result.error.message));
        }
      }, error => {
        this.message.error(this.l(error.message));
      });
    }
    else { // 验证未通过
      this.message.error(this.l('verify_failed_please_check_the_form_item'));
    }

  }

  getPathList() {
    if (this.model.startSiteId &&
      this.model.endSiteId) {
      this._service.searchHistoryBySiteOrCompanyUsingGET(this.model.startSiteId, this.model.endSiteId, this.model.startWarehouseId, this.model.endWarehouseId).subscribe(result => {

        this.tempPathList = result.result;
        if (result.result) {
          this.pathList = this.tempPathList.filter(m => m.launchsiteId == this.model.startSiteId
            && m.destinationsiteId == this.model.endSiteId);
          if (this.pathList.length != 0) {
            this.disabledSelect = false;
          } else {
            this.disabledSelect = true;
            this.model.type = "1";
          }
          this.getStartCompany();
          this.getEndCompany();
        }
        this.initializeMap();
      });
    } else {
      this.disabledSelect = true;
    }
  }

  pathWay() {
    this.initializeMap();
  }

  startCompany: WarehouseDTO;
  endCompany: WarehouseDTO;
  startSite: SiteDTO;
  endSite: SiteDTO;
  arriveTime: any;
  launchTime: any;
  totalTime: any;
  points = [];

  getPath() {
    const selectedPath = this.pathList.find(m => m.id == this.model.parentId);
    if (selectedPath) {

      this.points = [];
      //开始获取调度
      this._service.searchHistoryPoisitionByIdUsingGET(selectedPath.id).subscribe(result => {

        result.result.historyPositionDetails.map(m => {
          if (parseInt(m.longitude.toString()) != 0 && parseInt(m.latitude.toString()) != 0)
            this.points.push([m.longitude, m.latitude]);
        });

        if (this.points.length != 0) {
          this._center = this.points[0];
        }
        this.initializeMap();
        //这些点可以自己先定义
        //获取到所有的点
      });

      this.arriveTime = moment(selectedPath.arriveTime);
      this.launchTime = moment(selectedPath.launchTime);
      this.totalTime = moment(this.arriveTime - this.launchTime).format(this.l('hour_second_minute'));

      this.getStartCompany();
      this.getEndCompany();

    }
  }

  getStartCompany() {
    const list = this.startCompanyList.filter(m => m.id == this.model.startWarehouseId);
    if (list.length != 0) {
      this.startCompany = list[0];
      this._center = [this.startCompany.lng, this.startCompany.lat];
    }
  }

  getEndCompany() {
    const list = this.endCompanyList.filter(m => m.id == this.model.endWarehouseId);
    if (list.length != 0) {
      this.endCompany = list[0];
    }
  }

  pointGraphic: any;

  async initializeMap() {
    try {
      const [
        Map,
        MapView,
        ScaleBar,
        TileLayer,
        SketchViewModel,
        Graphic,
        GraphicsLayer] = await loadModules([
          'esri/Map',
          'esri/views/MapView',
          'esri/widgets/ScaleBar',
          'esri/layers/TileLayer',
          "esri/widgets/Sketch/SketchViewModel",
          "esri/Graphic",
          "esri/layers/GraphicsLayer",
          'dojo/domReady!'
        ], {
            url: AppConsts.arcgisMapUrl, css: AppConsts.arcgisStyleUrl
          });

      let editGraphic;
      const tempGraphicsLayer = new GraphicsLayer();
      const layer = new TileLayer({
        url: AppConsts.arcgisMapServerUrl
      });

      // Set type of map
      const map: esri.Map = new Map({
        // basemap: this._basemap,
        layers: [layer, tempGraphicsLayer]
      });

      const mapView: esri.MapView = new MapView({
        container: this.mapViewEl.nativeElement,
        center: this._center,
        zoom: this._zoom,
        map: map
      });

      // All resources in the MapView and the map have loaded.
      // Now execute additional processes
      mapView.when(() => {
        const scaleBar = new ScaleBar({
          view: mapView,
          unit: "dual" // The scale bar displays both metric and non-metric units.
        });
        mapView.ui.add(scaleBar, "bottom-left");

        const sketchViewModel = new SketchViewModel({
          view: mapView,
          layer: tempGraphicsLayer,
          polylineSymbol: {
            type: "simple-line", // autocasts as new SimpleLineSymbol()
            color: "green",
            width: "4",
            style: "solid"
          }
        });
        if (this.model.type === '1') {
          drawPath(this);
        } else {
          selectPath(this);
        }


        function selectPath(_that) {
          // const transJson = Graphic.fromJSON(JSON.parse(_that.selectedPath));
          // First create a point geometry (this is the location of the Titanic)
          const points = {
            type: "multipoint", // autocasts as new Point()
            points: [[
              _that.startSite.lng, _that.startSite.lat],
            [_that.endSite.lng, _that.endSite.lat]]
          };

          // Create a symbol for drawing the point
          const markerSymbol = {
            type: "picture-marker",  // autocasts as new PictureMarkerSymbol()
            url: "/assets/images/icon-flag.png",
            width: "24px",
            height: "24px",
            xoffset: "9px",
            yoffset: "10px"
          };
          // Create a graphic and add the geometry and symbol to it
          const pointGraphic = new Graphic({
            geometry: points,
            symbol: markerSymbol
          });
          const lineAtt = {
            Name: "Detail info",
            totalTime: _that.totalTime
          };

          const polylineGraphic = new Graphic({
            geometry: {
              type: "polyline", // autocasts as new Polyline()
              paths: _that.points
            },
            symbol: sketchViewModel.polylineSymbol,
            attributes: lineAtt,
            popupTemplate: { // autocasts as new PopupTemplate()
              title: "{Name}",
              content: [{
                type: "fields",
                fieldInfos: [{
                  fieldName: "totalTime"
                }]
              }]
            }
          });

          tempGraphicsLayer.addMany([pointGraphic, polylineGraphic]);
          _that.model.geoJson = JSON.stringify(polylineGraphic.toJSON());
        }

        function drawPath(_that) { // 绘制路径

          if (_that.startSite && _that.endSite) {
            // const transJson = Graphic.fromJSON(JSON.parse(_that.selectedPath));
            // First create a point geometry (this is the location of the Titanic)
            const points = {
              type: "multipoint", // autocasts as new Point()
              points: [[
                _that.startSite.lng, _that.startSite.lat],
              [_that.endSite.lng, _that.endSite.lat]]
            };

            // Create a symbol for drawing the point
            const markerSymbol = {
              type: "picture-marker",  // autocasts as new PictureMarkerSymbol()
              url: "/assets/images/icon-flag.png",
              width: "24px",
              height: "24px",
              xoffset: "9px",
              yoffset: "10px"
            };
            // Create a graphic and add the geometry and symbol to it
            const pointGraphic = new Graphic({
              geometry: points,
              symbol: markerSymbol
            });
            tempGraphicsLayer.add(pointGraphic);

          }
          setUpClickHandler();
          sketchViewModel.on("create-complete", addGraphic);
          sketchViewModel.on("update-complete", updateGraphic);
          sketchViewModel.on("update-cancel", updateGraphic);
          //*************************************************************
          // called when sketchViewModel's create-complete event is fired.
          //*************************************************************
          function addGraphic(event) {
            // Create a new graphic and set its geometry to
            // `create-complete` event geometry.
            const graphic = new Graphic({
              geometry: event.geometry,
              symbol: sketchViewModel.graphic.symbol
            });
            tempGraphicsLayer.add(graphic);
            _that.model.geoJson = JSON.stringify(graphic.toJSON());
          }

          //***************************************************************
          // called when sketchViewModel's update-complete or update-cancel
          // events are fired.
          //*************************************************************
          function updateGraphic(event) {
            // event.graphic is the graphic that user clicked on and its geometry
            // has not been changed. Update its geometry and add it to the layer
            event.graphic.geometry = event.geometry;
            tempGraphicsLayer.add(event.graphic);
            _that.model.geoJson = JSON.stringify(event.graphic.toJSON());
            // set the editGraphic to null update is complete or cancelled.
            editGraphic = null;
          }

          // ************************************************************************************
          // set up logic to handle geometry update and reflect the update on "tempGraphicsLayer"
          // ************************************************************************************
          function setUpClickHandler() {
            mapView.on("click", function (event) {
              mapView.hitTest(event).then(function (response) {
                var results = response.results;
                // Found a valid graphic
                if (results.length && results[results.length - 1].graphic) {
                  // Check if we're already editing a graphic
                  if (!editGraphic) {
                    // Save a reference to the graphic we intend to update
                    editGraphic = results[results.length - 1].graphic;
                    // Remove the graphic from the GraphicsLayer
                    // Sketch will handle displaying the graphic while being updated
                    tempGraphicsLayer.remove(editGraphic);
                    sketchViewModel.update(editGraphic);
                  }
                }
              });
            });
          }

          // activate the sketch to create a polyline
          var drawLineButton = document.getElementById("polylineButton");
          drawLineButton.onclick = function () {
            // set the sketch to create a polyline geometry
            sketchViewModel.create("polyline");
          };

          //**************
          // reset button
          //**************
          document.getElementById("resetBtn").onclick = function () {
            sketchViewModel.reset();
            tempGraphicsLayer.removeAll();
            _that.message.info(_that.l('clear_graphics'))

          };
        }
      });


    } catch (error) {
      console.log('We have an error: ' + error);
    }

  }


}
